package work.display.effect
{
	/**
	 * 
	 * @author 张峰
	 * @QQ:37520626
	 * @Email:7677@163.com
	 * @Date:2013-1-7 下午4:52:19
	 * 
	 */
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import zf.data.tools.Memory;
	import zf.display.FlashSpriteComponent;
	import zf.display.tools.DisplayObjectTool;
	/**
	 * 动画执行完毕事件 
	 * @eventType work.display.effect.TurnEffectEvent.COMPLETE
	 */
	[Bindable]
	[Event(name="complete", type="work.display.effect.TurnEffectEvent")]
	/**
	 * 点击事件 
	 * @eventType work.display.effect.TurnEffectEvent.CLICK
	 */
	[Bindable]
	[Event(name="click", type="work.display.effect.TurnEffectEvent")]
	public class TurnEffect extends FlashSpriteComponent
	{
		private var tw:Number;
		private var th:Number;
		private var xc:uint;
		private var yc:uint;
		private var dw:Number;
		private var dh:Number;
		
		private var ws:Number;
		private var hs:Number;
		
		private var diffuseX:uint;
		private var diffuseY:uint;
		
		private var bodyList:Array;
		private var moveType:uint=0;
		
		private var _isMove:Boolean=false;
		private var total:uint;
		private var idp:DisplayObject;
		private var turnType:uint=0;
		private var ndp:DisplayObject;
		
		private var timer:Timer;
		private var newTimer:Timer;
		/**
		 * 翻转动画 
		 * @param w 宽
		 * @param h 高
		 * @param xcut 横向分割
		 * @param ycut 纵向分割
		 * @param initDisplayObject 初始显示对象
		 * @param widthScale TurnSprite宽缩放比例
		 * @param heightScale TurnSprite高缩放比例
		 * 
		 */
		public function TurnEffect(w:Number,h:Number,xcut:uint,ycut:uint,initDisplayObject:DisplayObject=null,widthScale:Number=1,heightScale:Number=1)
		{
			super();
			tw=w;
			th=h;
			xc=xcut;
			yc=ycut;
			dw=tw/xc;
			dh=th/yc;
			
			ws=widthScale;
			hs=heightScale;
			
			idp=initDisplayObject;
			
			if(xc*yc>500)
			{
				trace("分割块大于500将引起性能问题");
			}
		}
		override protected function addStage():void
		{
			initThis();
		}
		override protected function removeStage():void
		{
			var i:uint;
			var j:uint;
			var ts:TurnSprite;
			
			for(i=0;i<yc;i++)
			{
				for(j=0;j<xc;j++)
				{
					ts=bodyList[i][j];
				}
				ts.removeEventListener(MouseEvent.CLICK,onClickTSHandler);
				this.removeChild(ts);
			}
			bodyList=null;
			
			timer.stop();
			timer.removeEventListener(TimerEvent.TIMER,onTimerHandler);
			timer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			
			newTimer.stop();
			newTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTurnCompleteHandler);
			
			timer=null;
			newTimer=null;
		}
		/**
		 * 是否正在动画 
		 * @return 
		 * 
		 */
		public function get isMove():Boolean
		{
			return _isMove;
		}
		
		private function initThis():void
		{
			var i:uint;
			var j:uint;
			
			
			var dx:Number;
			var dy:Number;
			var ts:TurnSprite;
			var bit:Bitmap=null;
			bodyList=[];
			for(i=0;i<yc;i++)
			{
				bodyList[i]=[];
				for(j=0;j<xc;j++)
				{
					dx=j*dw;
					dy=i*dh;
					if(idp)
					{
						bit=DisplayObjectTool.inciseBitmap(idp,dw,dh,dx,dy);
					}
					ts=new TurnSprite(dw*ws,dh*hs,bit);
					ts.data={ix:j,iy:i};
					ts.addEventListener(MouseEvent.CLICK,onClickTSHandler);
					ts.x=dx;
					ts.y=dy;
					this.addChild(ts);
					bodyList[i][j]=ts;
				}
			}
			timer=new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER,onTimerHandler);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			
			newTimer=new Timer(1000*(TurnSprite.tweenTime+0.1),1);
			newTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onTurnCompleteHandler);
		}
		private function onClickTSHandler(e:MouseEvent):void
		{
			var ts:TurnSprite=TurnSprite(e.currentTarget);
			e.stopPropagation();
			this.dispatchEvent(new TurnEffectEvent(TurnEffectEvent.CLICK,ts.data));
		}
		/**
		 * 翻转 
		 * @param newDiaplayObject 新显示对象
		 * @param interval 间隔时间 秒
		 * @param type 翻转方式
		 * @return 是否成功执行
		 */
		public function turn(newDiaplayObject:DisplayObject,interval:Number=0,type:uint=0):Boolean
		{
			if(_isMove)
			{
				return false;
			}
			_isMove=true;
			turnType=type;
			ndp=newDiaplayObject;
			if(interval==0)
			{
				var i:uint;
				var j:uint;
				
				var dx:Number;
				var dy:Number;
				var ts:TurnSprite;
				var bit:Bitmap=null;
				for(i=0;i<yc;i++)
				{
					for(j=0;j<xc;j++)
					{
						dx=j*dw;
						dy=i*dh;
						bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
						ts=bodyList[i][j];
						turnTS(ts,bit);
					}
				}
				distributeEvent();
			}else
			{
				switch(turnType)
				{
					case 0:
						//x行
						total=yc;
						break;
					case 1:
						total=xc;
						//y行
						break;
					case 2:
						//x单个
					case 3:
						//y单个
					case 4:
						//x单个蛇形
					case 5:
						//y单个蛇形
						total=xc*yc;
						break;
					case 6:
						total=xc+yc-1;
						//斜向
						break;
					default:
						total=yc;
						break;
				}
				timer.reset();
				timer.delay=interval*1000;
				timer.repeatCount=total;
				timer.start();
			}
			return true;
		}
		private function turnTS(ts:TurnSprite,bit:Bitmap,type:int=-1):void
		{
			if(type==-1)
			{
				type=moveType;
			}
			switch(type)
			{
				case 0:
					ts.turnX(bit);
					break;
				case 1:
					ts.turnY(bit);
					break;
				case 2:
					ts.turnOBX(bit);
					break;
				case 3:
					ts.turnOBY(bit);
					break;
			}
			
		}
		private function onTimerHandler(e:TimerEvent):void
		{
			
			var k:uint=timer.currentCount-1;
			switch(turnType)
			{
				case 0:
					//x行
					hangX(k);
					break;
				case 1:
					//y行
					hangY(k);
					break;
				case 2:
					//x单个
					geX(k);
					break;
				case 3:
					//y单个
					geY(k);
					break;
				case 4:
					//x蛇形单个
					geXshe(k);
					break;
				case 5:
					//y蛇形单个
					geYshe(k);
					break;
				case 6:
					//斜向
					xie(k);
					break;
				case 7:
					//扩散
					diffuse(k);
					break;
				default:
					hangX(k);
					break;
			}			
		}
		private function onTimerCompleteHandler(e:TimerEvent):void
		{
			//timer.removeEventListener(TimerEvent.TIMER,onTimerHandler);
			//timer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			
			//timer.stop();
			distributeEvent();
		}
		private function distributeEvent():void
		{
			//var newTimer:Timer=new Timer(1000*(TurnSprite.tweenTime+0.1),1);
			//newTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onTurnCompleteHandler);
			newTimer.reset();
			newTimer.start();
		}
		private function onTurnCompleteHandler(e:TimerEvent):void
		{
			//var timer:Timer=Timer(e.currentTarget);
			//timer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTurnCompleteHandler);
			moveType=(moveType+1)%4;
			_isMove=false;
			
			this.dispatchEvent(new TurnEffectEvent(TurnEffectEvent.COMPLETE));
			Memory.gc();
			
		}
		
		private function hangX(k:uint):void
		{
			var i:uint;
			
			var dx:Number;
			var dy:Number;
			var ts:TurnSprite;
			var bit:Bitmap=null;
			dy=k*dh;
			for(i=0;i<xc;i++)
			{
				dx=i*dw;
				bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
				ts=bodyList[k][i];
				turnTS(ts,bit);
			}
		}
		private function hangY(k:uint):void
		{
			var i:uint;
			
			var dx:Number;
			var dy:Number;
			var ts:TurnSprite;
			var bit:Bitmap=null;
			dx=k*dw;
			for(i=0;i<yc;i++)
			{
				dy=i*dh;
				bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
				ts=bodyList[i][k];
				turnTS(ts,bit);
			}
		}
		private function geX(k:uint):void
		{
			var i:uint=Math.floor(k/xc);
			var j:uint=k%xc;
			
			var dx:Number=j*dw;
			var dy:Number=i*dh;
			
			var bit:Bitmap=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
			var ts:TurnSprite=bodyList[i][j];
			turnTS(ts,bit);
		}
		private function geY(k:uint):void
		{
			var i:uint=k%yc;
			var j:uint=Math.floor(k/yc);
			
			var dx:Number=j*dw;
			var dy:Number=i*dh;
			
			var bit:Bitmap=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
			var ts:TurnSprite=bodyList[i][j];
			turnTS(ts,bit);
		}
		private function geXshe(k:uint):void
		{
			var i:uint=Math.floor(k/xc);
			var j:uint=k%xc;
			if(i%2==1)
			{
				j=xc-j-1;
			}
			var dx:Number=j*dw;
			var dy:Number=i*dh;
			
			var bit:Bitmap=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
			var ts:TurnSprite=bodyList[i][j];
			turnTS(ts,bit);
		}
		private function geYshe(k:uint):void
		{
			var i:uint=k%yc;
			var j:uint=Math.floor(k/yc);
			if(j%2==1)
			{
				i=yc-i-1;
			}
			var dx:Number=j*dw;
			var dy:Number=i*dh;
			
			var bit:Bitmap=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
			var ts:TurnSprite=bodyList[i][j];
			turnTS(ts,bit);
		}
		private function xie(k:uint):void
		{
			var i:uint;
			var j:uint;
			
			var dx:Number;
			var dy:Number;
			var ts:TurnSprite;
			var bit:Bitmap=null;
			
			
			for(var m:uint=0;m<=k;m++)
			{
				i=m;
				j=k-m;
				if(i>yc-1)
				{
					continue;
				}
				if(j>xc-1)
				{
					continue;
				}
				
				dx=j*dw;
				dy=i*dh;
				bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
				ts=bodyList[i][j];
				turnTS(ts,bit);
			}
		}
		/**
		 * 扩散翻转 
		 * @param nx 扩散点X
		 * @param ny 扩散点Y
		 * @param newDiaplayObject 新显示对象
		 * @param interval 间隔时间 秒
		 * @return 是否成功执行
		 * 
		 */
		public function diffuseTurn(nx:uint,ny:uint,newDiaplayObject:DisplayObject,interval:Number=0):Boolean
		{
			if(interval==0)
			{
				return turn(newDiaplayObject,interval,0);
			}
			if(_isMove)
			{
				return false;
			}
			
			_isMove=true;
			diffuseX=nx;
			diffuseY=ny;
			turnType=7;
			ndp=newDiaplayObject;
			
			var xt:uint=Math.max(nx+1,xc-nx);
			var yt:uint=Math.max(ny+1,yc-ny);
			total=Math.max(xt,yt);
			moveType=(moveType+4-1)%4;
			
			//var timer:Timer=new Timer(interval*1000,total);
			//timer.addEventListener(TimerEvent.TIMER,onTimerHandler);
			//timer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			
			timer.reset();
			timer.delay=interval*1000;
			timer.repeatCount=total;
			timer.start();
			return true;
		}
		private function diffuse(k:uint):void
		{
			var i:int;
			var j:int;
			
			var dx:Number;
			var dy:Number;
			var ts:TurnSprite;
			var bit:Bitmap=null;
			
			var startx:int=diffuseX-k;
			var endx:int=diffuseX+k+1;
			
			var starty:int=diffuseY-k;
			var endy:int=diffuseY+k+1;
			
			i=starty;
			if(i>=0)
			{
				
				j=startx>=0?startx:0;
				while(j<endx)
				{
					if(j>xc-1)
					{
						break;
					}
					dx=j*dw;
					dy=i*dh;
					bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
					ts=bodyList[i][j];
					turnTS(ts,bit,2);
					j++;
				}
			}
			i=endy-1;
			if(i<yc)
			{
				
				j=startx>0?startx:0;
				while(j<endx)
				{
					if(j>xc-1)
					{
						break;
					}
					dx=j*dw;
					dy=i*dh;
					bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
					ts=bodyList[i][j];
					turnTS(ts,bit,0);
					j++;
				}
			}
			
			j=startx;
			if(j>=0)
			{
				
				i=starty+1;
				i=i>0?i:0;
				while(i<endy-1)
				{
					if(i>yc-1)
					{
						break;
					}
					dx=j*dw;
					dy=i*dh;
					bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
					ts=bodyList[i][j];
					turnTS(ts,bit,1);
					i++;
				}
			}
			
			j=endx-1;
			if(j<xc)
			{
				
				i=starty+1;
				i=i>0?i:0;
				while(i<endy-1)
				{
					if(i>yc-1)
					{
						break;
					}
					dx=j*dw;
					dy=i*dh;
					bit=DisplayObjectTool.inciseBitmap(ndp,dw,dh,dx,dy);
					ts=bodyList[i][j];
					turnTS(ts,bit,3);
					i++;
				}
			}
		}
	}
}